package com.zjm.collections.map;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.concurrent.locks.LockSupport;

// 制定1.7版本运行，模拟了 哈希卖铺 循环李链表的场景
public class HashMap17Test {
    public static void main1(String[] args) throws Exception {
        HashMap<String, String> map = new HashMap<>();
        Field tableField = HashMap.class.getDeclaredField("table");
        tableField.setAccessible(true);

        // 重点 - 将Hash值计算出来的index相同的数据插入到Map中去。
        for (int i = 0; i < 1000; i++) {
            String key = "a" + i;
            // hash值
            int h = key.hashCode();
            int hash = h ^ (h >>> 16);
            // hashmap数组长度
            Object[] table = ((Object[]) tableField.get(map));
            int tableSize = 16;
            if (table != null) {
                tableSize = ((Object[]) tableField.get(map)).length;
            }
            // key对于的下标
            int index = ((tableSize - 1) & hash);
            // 只插入下标为10的数据
            if (index == 10) {
                map.put(key, "xxx");
                // 打印当前的table长度，看看是不是扩容了
                System.out.println(((Object[]) tableField.get(map)).length);
            }
        }
    }

    // hashmap 并发扩容产生循环列表场景模拟
    public static void main(String[] args) throws InterruptedException {
        HashMap1_7<String, String> map = new HashMap1_7<String, String>(2, 1);
        map.put("1", "1");
        map.put("5", "5");

        Thread thread1 = new Thread(() -> {
            System.out.println("thread1 启动");
            map.put("9", "9");
            //System.out.println("thread1 put完成：" + map);
            //System.out.println("thread1 执行完成 唤醒thread2");
            //LockSupport.unpark(thread2);
        });
        thread1.setName("thread1");

        Thread thread2 = new Thread(() -> {
            System.out.println("thread2 启动");
            map.put("13", "13");
            System.out.println("thread2 put完成：" + map);
            System.out.println("thread2 执行完成 唤醒thread1");
            LockSupport.unpark(thread1);
        });
        thread2.setName("thread2");

        map.setThread1(thread1);

        thread1.start();
        Thread.sleep(10);
        thread2.start();

        Thread.sleep(2000);
        String key = "13"; // 线程1put完成以后 map {1, 5, 9} ,map.get(1 | 5 | 9) 都没有问题，但是如果获取 13,17,21,25 .... 会进入死循环
        //System.out.println(map);
        System.out.println("两秒后查看map: get key-" + key);
        System.out.println(map.get(key));


    }
    //System.out.println( & 15);
    // long index = 0b11011011111000010 & 0b1111;
    // long index = 0b11011011111000010 % 10000;
    public static void main2(String[] args) {
        long t1 = System.currentTimeMillis();
        for (long i  = 0; i < 10000000000L;i ++) {
            long index = 0b11011011111000010 & 0b1111;
        }
        long t2 = System.currentTimeMillis();
        System.out.println(t2 - t1);



    }
}
